package com.example.service.impl;

import com.example.dto.AvatarUploadDTO;
import com.example.entity.User;
import com.example.exception.BusinessException;
import com.example.mapper.UserMapper;
import com.example.service.AvatarService;
import com.example.service.MinioService;
import com.example.util.UserContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 头像服务实现类
 */
@Slf4j
@Service
public class AvatarServiceImpl implements AvatarService {
    
    @Autowired
    private MinioService minioService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserContextUtil userContextUtil;
    
    // 允许的头像文件类型
    private static final String[] ALLOWED_AVATAR_TYPES = {
        "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp", "image/webp"
    };
    
    // 头像文件最大大小 (2MB)
    private static final long MAX_AVATAR_SIZE = 2 * 1024 * 1024;
    
    @Override
    public AvatarUploadDTO uploadAvatar(MultipartFile file) {
        try {
            log.info("开始上传用户头像: {}, 大小: {} bytes", file.getOriginalFilename(), file.getSize());
            
            // 验证头像文件
            validateAvatarFile(file);
            
            // 上传到MinIO的avatars文件夹
            String objectName = minioService.uploadFile(file, "avatars");
            String avatarUrl = minioService.getFileUrl(objectName);
            
            // 构建返回数据
            AvatarUploadDTO result = new AvatarUploadDTO();
            result.setAvatarUrl(avatarUrl);
            result.setFilePath(objectName);
            result.setOriginalName(file.getOriginalFilename());
            result.setFileSize(file.getSize());
            result.setContentType(file.getContentType());
            
            log.info("头像上传成功: {} -> {}", file.getOriginalFilename(), objectName);
            
            return result;
            
        } catch (Exception e) {
            log.error("头像上传失败: {}", file.getOriginalFilename(), e);
            if (e instanceof BusinessException) {
                throw e;
            }
            throw BusinessException.fileUploadFailed();
        }
    }
    
    @Override
    @Transactional
    public void updateUserAvatar(Long userId, String avatarUrl) {
        try {
            log.info("开始更新用户头像: userId={}, avatarUrl={}", userId, avatarUrl);

            // 查询用户
            User user = userMapper.selectById(userId);
            log.info("查询到的用户信息: {}", user != null ? user.getUsername() : "null");

            if (user == null) {
                log.error("用户不存在: userId={}", userId);
                throw BusinessException.userNotFound();
            }

            // 保存旧头像URL用于删除
            String oldAvatarUrl = user.getAvatar();
            log.info("用户当前头像URL: {}", oldAvatarUrl);

            // 更新用户头像
            user.setAvatar(avatarUrl);
            user.setUpdateTime(LocalDateTime.now());

            log.info("准备执行数据库更新，用户对象: id={}, username={}, avatar={}",
                    user.getId(), user.getUsername(), user.getAvatar());

            int updateResult = userMapper.updateById(user);
            log.info("数据库更新结果: {}", updateResult);

            if (updateResult <= 0) {
                log.error("数据库更新失败，影响行数: {}", updateResult);
                throw new BusinessException("50002", "数据库更新失败");
            }

            // 删除旧头像文件（如果存在且不为空）
            if (oldAvatarUrl != null && !oldAvatarUrl.trim().isEmpty()) {
                try {
                    String oldObjectName = extractObjectNameFromUrl(oldAvatarUrl);
                    minioService.deleteFile(oldObjectName);
                    log.info("删除旧头像文件: {}", oldObjectName);
                } catch (Exception e) {
                    log.warn("删除旧头像文件失败: {}", oldAvatarUrl, e);
                }
            }

            log.info("用户头像更新成功: userId={}, avatarUrl={}", userId, avatarUrl);

        } catch (Exception e) {
            log.error("更新用户头像失败: userId={}, avatarUrl={}", userId, avatarUrl, e);
            if (e instanceof BusinessException) {
                throw e;
            }
            throw new BusinessException("50001", "更新用户头像失败: " + e.getMessage());
        }
    }
    
    @Override
    public void deleteUserAvatar(Long userId) {
        try {
            // 查询用户
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw BusinessException.userNotFound();
            }
            
            // 删除头像文件（如果存在）
            String avatarUrl = user.getAvatar();
            if (avatarUrl != null && !avatarUrl.trim().isEmpty()) {
                try {
                    String objectName = extractObjectNameFromUrl(avatarUrl);
                    minioService.deleteFile(objectName);
                    log.info("删除头像文件: {}", objectName);
                } catch (Exception e) {
                    log.warn("删除头像文件失败: {}", avatarUrl, e);
                }
            }
            
            // 清空用户头像字段
            user.setAvatar(null);
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
            
            log.info("用户头像删除成功: userId={}", userId);
            
        } catch (Exception e) {
            log.error("删除用户头像失败: userId={}", userId, e);
            if (e instanceof BusinessException) {
                throw e;
            }
            throw new BusinessException("50001", "删除用户头像失败");
        }
    }
    
    /**
     * 验证头像文件
     */
    private void validateAvatarFile(MultipartFile file) {
        // 检查文件是否为空
        if (file == null || file.isEmpty()) {
            throw BusinessException.dataValidationFailed("请选择要上传的头像文件");
        }
        
        // 检查文件大小
        if (file.getSize() > MAX_AVATAR_SIZE) {
            throw new BusinessException("60005", "头像文件大小不能超过2MB");
        }
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !Arrays.asList(ALLOWED_AVATAR_TYPES).contains(contentType.toLowerCase())) {
            throw new BusinessException("60006", "头像文件格式不支持，仅支持jpg、png、gif、bmp、webp格式");
        }
        
        // 检查文件名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            throw BusinessException.dataValidationFailed("头像文件名不能为空");
        }
    }
    
    /**
     * 从URL中提取对象名
     */
    private String extractObjectNameFromUrl(String url) {
        if (url == null || url.trim().isEmpty()) {
            return "";
        }
        
        // 查找最后一个/avatars/的位置
        int avatarsIndex = url.lastIndexOf("/avatars/");
        if (avatarsIndex == -1) {
            return "";
        }
        
        return url.substring(avatarsIndex + 1); // 去掉前面的/
    }
} 